#include "canionWarp.h"

CanionWarp::CanionWarp(int argc, char *argv[])
{
    bool pelea = false;
	
	if (argc == 5)
	{
		/* Otros tiros. */
		pelea = true;		
	}
	else if (argc != 3)
	{
		/* Error. */		
		cerr << "La cantidad de parámetros pasada es incorrecta. " << endl;		
	}
		
	int a, n;
	double aux;	
	
	/* Archivos. */
	string 	 pos (argv[1]);
	ifstream posicion(pos.c_str());		
	
	if (!posicion.is_open())
    {
        cerr << "No se pudo abrir el archivo!" << endl;
        exit(1);
    } 
	
	/* Leer posición. */
	posicion >> a >> dimension;
    n = dimension;
    
    //~ cout << "n: " << n << endl;
    
    /* Inicializar vectores y matrices. */
    pos_enemiga 	= Vector(n, 0);
    pos_propia 		= Vector(n, 0);
	impacto_propio 	= Vector(n, 0);
	impacto_enemigo	= Vector(n, 0);
	matriz_propia 	= Matriz (n, Vector(n, 0));
	matriz_enemiga 	= Matriz (n, Vector(n, 0));
	hilbert 		= Matriz (n, Vector(n, 0));
        
	/* Crear la matríz de Hilbert de dimensión n. */	
	Hilbert(hilbert, n);	
	
	/* Leer la posición. */
	forn(i, n)
	{
		posicion >> aux;
		pos_propia[i] = aux;
		//~ cout << pos_propia[i] << " ";
	}
	
	//~ cout << "Posición Propia" << endl;
	//~ mostrarVector(pos_propia, dimension);
		
	if (pelea)
	{		
		/* Más archivos. */
		string 	 ult (argv[3]);
		ifstream ultimo(ult.c_str());
	
		/* Último: d y matríz. */		
		ultimo >> turno >> a;
		
		if (a != n)
		{
			cerr << "Error! No es la misma dimensión" << endl;
			exit(1);
		}
		
		/* Leer impacto del enemigo. */
		forn(i, n)
		{		
			ultimo >> aux;
			impacto_enemigo[i] = aux;
		}		
		
		/* Leer matríz. */
		forn(i, n)
		{
			forn(j, n)
			{
				ultimo >> aux;
				matriz_enemiga[i][j] = aux;
			}
		}		
		
		ultimo.close();		
	}
	else
	{
		turno = 0;
	}	
    
    posicion.close();
}

void CanionWarp::crearMatriz()
{
    if (turno == 0)
    {		
		matrizInicial(matriz_propia, hilbert, pos_enemiga, pos_propia, dimension);		
	}
    else
    {
		PLUPivoteo(matriz_enemiga, impacto_enemigo, pos_enemiga, dimension);
		buscarMatriz(matriz_propia, hilbert, pos_enemiga, pos_propia, dimension);
	}
	
	matrizPorVector(matriz_propia, pos_propia, impacto_propio, dimension);
	//~ cout << "Matriz Propia" << endl;
	//~ mostrarMatriz(matriz_propia, dimension);
	//~ cout << "Posición Propia" << endl;
	//~ mostrarVector(pos_propia, dimension);
	//~ cout << "Impacto Propio" << endl;
	//~ mostrarVector(impacto_propio, dimension);	
	//~ 
	//~ cout << "pos_enemiga" << endl;
	//~ mostrarVector(pos_enemiga, dimension);
}

void CanionWarp::escribirArchivo(string destino)
{
	turno++;
	
	ofstream salida(destino.c_str());
	salida.precision(20);
	salida.setf(std::ios_base::scientific, std::ios_base::floatfield);
	
	int n = dimension;
	
	if(salida.is_open()) 
	{
		/* Escribir el turno. */
		salida << turno << endl;
		/* Escribir la dimensión. */		
		salida << dimension << endl;		
		/* Escribir el disparo. */
		forn(i, n)
			salida << impacto_propio[i] << " ";
		salida << endl;
		/* Escribir la matríz warp. */
		forn(i, n)
		{
			forn(j, n)
				salida << matriz_propia[i][j] << " ";
			salida << endl;			
		}		
		salida.close();
	}
	else 
	{
		cerr << "No se pudo guardar el archivo!" << endl;
		exit(1);
	}
}
